package com.buli.util;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.zip.*;

public class GADMGeoJsonDownloader {

    // 国家列表：ISO3 -> 中文名 -> 英文名
    private static final Map<String, String> COUNTRY_MAP = new HashMap<>();

    static {
        // 初始化国家列表（ISO3 -> 中文名）
        COUNTRY_MAP.put("AFG", "阿富汗 Afghanistan");
        COUNTRY_MAP.put("ALB", "阿尔巴尼亚 Albania");
        COUNTRY_MAP.put("DZA", "阿尔及利亚 Algeria");
        COUNTRY_MAP.put("ASM", "美属萨摩亚 American Samoa");
        COUNTRY_MAP.put("AND", "安道尔 Andorra");
        COUNTRY_MAP.put("AGO", "安哥拉 Angola");
        COUNTRY_MAP.put("AIA", "安圭拉 Anguilla");
        COUNTRY_MAP.put("ATA", "南极洲 Antarctica");
        COUNTRY_MAP.put("ATG", "安提瓜和巴布达 Antigua and Barbuda");
        COUNTRY_MAP.put("ARG", "阿根廷 Argentina");
        COUNTRY_MAP.put("ARM", "亚美尼亚 Armenia");
        COUNTRY_MAP.put("ABW", "阿鲁巴 Aruba");
        COUNTRY_MAP.put("AUS", "澳大利亚 Australia");
        COUNTRY_MAP.put("AUT", "奥地利 Austria");
        COUNTRY_MAP.put("AZE", "阿塞拜疆 Azerbaijan");
        COUNTRY_MAP.put("BHS", "巴哈马 Bahamas");
        COUNTRY_MAP.put("BHR", "巴林 Bahrain");
        COUNTRY_MAP.put("BGD", "孟加拉国 Bangladesh");
        COUNTRY_MAP.put("BRB", "巴巴多斯 Barbados");
        COUNTRY_MAP.put("BLR", "白俄罗斯 Belarus");
        COUNTRY_MAP.put("BEL", "比利时 Belgium");
        COUNTRY_MAP.put("BLZ", "伯利兹 Belize");
        COUNTRY_MAP.put("BEN", "贝宁 Benin");
        COUNTRY_MAP.put("BMU", "百慕大 Bermuda");
        COUNTRY_MAP.put("BTN", "不丹 Bhutan");
        COUNTRY_MAP.put("BOL", "玻利维亚 Bolivia");
        COUNTRY_MAP.put("BIH", "波黑 Bosnia and Herzegovina");
        COUNTRY_MAP.put("BWA", "博茨瓦纳 Botswana");
        COUNTRY_MAP.put("BVT", "布维岛 Bouvet Island");
        COUNTRY_MAP.put("BRA", "巴西 Brazil");
        COUNTRY_MAP.put("VGB", "英属维尔京群岛 British Virgin Islands");
        COUNTRY_MAP.put("BRN", "文莱 Brunei");
        COUNTRY_MAP.put("BGR", "保加利亚 Bulgaria");
        COUNTRY_MAP.put("BFA", "布基纳法索 Burkina Faso");
        COUNTRY_MAP.put("BDI", "布隆迪 Burundi");
        COUNTRY_MAP.put("KHM", "柬埔寨 Cambodia");
        COUNTRY_MAP.put("CMR", "喀麦隆 Cameroon");
        COUNTRY_MAP.put("CAN", "加拿大 Canada");
        COUNTRY_MAP.put("CPV", "佛得角 Cape Verde");
        COUNTRY_MAP.put("CYM", "开曼群岛 Cayman Islands");
        COUNTRY_MAP.put("CAF", "中非 Central African Republic");
        COUNTRY_MAP.put("TCD", "乍得 Chad");
        COUNTRY_MAP.put("CHL", "智利 Chile");
        COUNTRY_MAP.put("CHN", "中国 China");
        COUNTRY_MAP.put("CXR", "圣诞岛 Christmas Island");
        COUNTRY_MAP.put("CCK", "科科斯群岛 Cocos (Keeling) Islands");
        COUNTRY_MAP.put("COL", "哥伦比亚 Colombia");
        COUNTRY_MAP.put("COM", "科摩罗 Comoros");
        COUNTRY_MAP.put("COG", "刚果 Congo");
        COUNTRY_MAP.put("COD", "刚果（金） Democratic Republic of the Congo");
        COUNTRY_MAP.put("COK", "库克群岛 Cook Islands");
        COUNTRY_MAP.put("CRI", "哥斯达黎加 Costa Rica");
        COUNTRY_MAP.put("HRV", "克罗地亚 Croatia");
        COUNTRY_MAP.put("CUB", "古巴 Cuba");
        COUNTRY_MAP.put("CUW", "库拉索 Curaçao");
        COUNTRY_MAP.put("CYP", "塞浦路斯 Cyprus");
        COUNTRY_MAP.put("CZE", "捷克 Czechia");
        COUNTRY_MAP.put("DNK", "丹麦 Denmark");
        COUNTRY_MAP.put("DJI", "吉布提 Djibouti");
        COUNTRY_MAP.put("DMA", "多米尼克 Dominica");
        COUNTRY_MAP.put("DOM", "多米尼加 Dominican Republic");
        COUNTRY_MAP.put("TLS", "东帝汶 East Timor");
        COUNTRY_MAP.put("ECU", "厄瓜多尔 Ecuador");
        COUNTRY_MAP.put("EGY", "埃及 Egypt");
        COUNTRY_MAP.put("SLV", "萨尔瓦多 El Salvador");
        COUNTRY_MAP.put("GNQ", "赤道几内亚 Equatorial Guinea");
        COUNTRY_MAP.put("ERI", "厄立特里亚 Eritrea");
        COUNTRY_MAP.put("EST", "爱沙尼亚 Estonia");
        COUNTRY_MAP.put("ETH", "埃塞俄比亚 Ethiopia");
        COUNTRY_MAP.put("FLK", "福克兰群岛 Falkland Islands");
        COUNTRY_MAP.put("FRO", "法罗群岛 Faroe Islands");
        COUNTRY_MAP.put("FJI", "斐济 Fiji");
        COUNTRY_MAP.put("FIN", "芬兰 Finland");
        COUNTRY_MAP.put("FRA", "法国 France");
        COUNTRY_MAP.put("GUF", "法属圭亚那 French Guiana");
        COUNTRY_MAP.put("PYF", "法属波利尼西亚 French Polynesia");
        COUNTRY_MAP.put("ATF", "法属南部领地 French Southern Territories");
        COUNTRY_MAP.put("GAB", "加蓬 Gabon");
        COUNTRY_MAP.put("GMB", "冈比亚 Gambia");
        COUNTRY_MAP.put("GEO", "格鲁吉亚 Georgia");
        COUNTRY_MAP.put("DEU", "德国 Germany");
        COUNTRY_MAP.put("GHA", "加纳 Ghana");
        COUNTRY_MAP.put("GIB", "直布罗陀 Gibraltar");
        COUNTRY_MAP.put("GRC", "希腊 Greece");
        COUNTRY_MAP.put("GRL", "格陵兰 Greenland");
        COUNTRY_MAP.put("GRD", "格林纳达 Grenada");
        COUNTRY_MAP.put("GLP", "瓜德罗普 Guadeloupe");
        COUNTRY_MAP.put("GUM", "关岛 Guam");
        COUNTRY_MAP.put("GTM", "危地马拉 Guatemala");
        COUNTRY_MAP.put("GGY", "根西岛 Guernsey");
        COUNTRY_MAP.put("GIN", "几内亚 Guinea");
        COUNTRY_MAP.put("GNB", "几内亚比绍 Guinea-Bissau");
        COUNTRY_MAP.put("GUY", "圭亚那 Guyana");
        COUNTRY_MAP.put("HTI", "海地 Haiti");
        COUNTRY_MAP.put("HND", "洪都拉斯 Honduras");
        COUNTRY_MAP.put("HKG", "香港 Hong Kong");
        COUNTRY_MAP.put("HUN", "匈牙利 Hungary");
        COUNTRY_MAP.put("ISL", "冰岛 Iceland");
        COUNTRY_MAP.put("IND", "印度 India");
        COUNTRY_MAP.put("IDN", "印度尼西亚 Indonesia");
        COUNTRY_MAP.put("IRN", "伊朗 Iran");
        COUNTRY_MAP.put("IRQ", "伊拉克 Iraq");
        COUNTRY_MAP.put("IRL", "爱尔兰 Ireland");
        COUNTRY_MAP.put("IMN", "马恩岛 Isle of Man");
        COUNTRY_MAP.put("ISR", "以色列 Israel");
        COUNTRY_MAP.put("ITA", "意大利 Italy");
        COUNTRY_MAP.put("JAM", "牙买加 Jamaica");
        COUNTRY_MAP.put("JPN", "日本 Japan");
        COUNTRY_MAP.put("JEY", "泽西岛 Jersey");
        COUNTRY_MAP.put("JOR", "约旦 Jordan");
        COUNTRY_MAP.put("KAZ", "哈萨克斯坦 Kazakhstan");
        COUNTRY_MAP.put("KEN", "肯尼亚 Kenya");
        COUNTRY_MAP.put("KGZ", "吉尔吉斯斯坦 Kyrgyzstan");
        COUNTRY_MAP.put("LAO", "老挝 Laos");
        COUNTRY_MAP.put("LVA", "拉脱维亚 Latvia");
        COUNTRY_MAP.put("LBN", "黎巴嫩 Lebanon");
        COUNTRY_MAP.put("LSO", "莱索托 Lesotho");
        COUNTRY_MAP.put("LBR", "利比里亚 Liberia");
        COUNTRY_MAP.put("LBY", "利比亚 Libya");
        COUNTRY_MAP.put("LIE", "列支敦士登 Liechtenstein");
        COUNTRY_MAP.put("LTU", "立陶宛 Lithuania");
        COUNTRY_MAP.put("LUX", "卢森堡 Luxembourg");
        COUNTRY_MAP.put("MAC", "澳门 Macau");
        COUNTRY_MAP.put("MKD", "北马其顿 North Macedonia");
        COUNTRY_MAP.put("MDG", "马达加斯加 Madagascar");
        COUNTRY_MAP.put("MWI", "马拉维 Malawi");
        COUNTRY_MAP.put("MYS", "马来西亚 Malaysia");
        COUNTRY_MAP.put("MDV", "马尔代夫 Maldives");
        COUNTRY_MAP.put("MLI", "马里 Mali");
        COUNTRY_MAP.put("MLT", "马耳他 Malta");
        COUNTRY_MAP.put("MHL", "马绍尔群岛 Marshall Islands");
        COUNTRY_MAP.put("MTQ", "马提尼克 Martinique");
        COUNTRY_MAP.put("MRT", "毛里塔尼亚 Mauritania");
        COUNTRY_MAP.put("MUS", "毛里求斯 Mauritius");
        COUNTRY_MAP.put("MYT", "马约特 Mayotte");
        COUNTRY_MAP.put("MEX", "墨西哥 Mexico");
        COUNTRY_MAP.put("FSM", "密克罗尼西亚 Micronesia");
        COUNTRY_MAP.put("MDA", "摩尔多瓦 Moldova");
        COUNTRY_MAP.put("MCO", "摩纳哥 Monaco");
        COUNTRY_MAP.put("MNG", "蒙古 Mongolia");
        COUNTRY_MAP.put("MNE", "黑山 Montenegro");
        COUNTRY_MAP.put("MSR", "蒙特塞拉特 Montserrat");
        COUNTRY_MAP.put("MAR", "摩洛哥 Morocco");
        COUNTRY_MAP.put("MOZ", "莫桑比克 Mozambique");
        COUNTRY_MAP.put("MMR", "缅甸 Myanmar");
        COUNTRY_MAP.put("NAM", "纳米比亚 Namibia");
        COUNTRY_MAP.put("NRU", "瑙鲁 Nauru");
        COUNTRY_MAP.put("NPL", "尼泊尔 Nepal");
        COUNTRY_MAP.put("NLD", "荷兰 Netherlands");
        COUNTRY_MAP.put("NCL", "新喀里多尼亚 New Caledonia");
        COUNTRY_MAP.put("NZL", "新西兰 New Zealand");
        COUNTRY_MAP.put("NIC", "尼加拉瓜 Nicaragua");
        COUNTRY_MAP.put("NER", "尼日尔 Niger");
        COUNTRY_MAP.put("NGA", "尼日利亚 Nigeria");
        COUNTRY_MAP.put("NIU", "纽埃 Niue");
        COUNTRY_MAP.put("NFK", "诺福克岛 Norfolk Island");
        COUNTRY_MAP.put("MNP", "北马里亚纳群岛 Northern Mariana Islands");
        COUNTRY_MAP.put("NOR", "挪威 Norway");
        COUNTRY_MAP.put("OMN", "阿曼 Oman");
        COUNTRY_MAP.put("PAK", "巴基斯坦 Pakistan");
        COUNTRY_MAP.put("PLW", "帕劳 Palau");
        COUNTRY_MAP.put("PSE", "巴勒斯坦 Palestine");
        COUNTRY_MAP.put("PAN", "巴拿马 Panama");
        COUNTRY_MAP.put("PNG", "巴布亚新几内亚 Papua New Guinea");
        COUNTRY_MAP.put("PRY", "巴拉圭 Paraguay");
        COUNTRY_MAP.put("PER", "秘鲁 Peru");
        COUNTRY_MAP.put("PHL", "菲律宾 Philippines");
        COUNTRY_MAP.put("PCN", "皮特凯恩岛 Pitcairn");
        COUNTRY_MAP.put("POL", "波兰 Poland");
        COUNTRY_MAP.put("PRT", "葡萄牙 Portugal");
        COUNTRY_MAP.put("PRI", "波多黎各 Puerto Rico");
        COUNTRY_MAP.put("QAT", "卡塔尔 Qatar");
        COUNTRY_MAP.put("KOR", "韩国 South Korea");
        COUNTRY_MAP.put("MDA", "摩尔多瓦 Moldova");
        COUNTRY_MAP.put("ROU", "罗马尼亚 Romania");
        COUNTRY_MAP.put("RUS", "俄罗斯 Russia");
        COUNTRY_MAP.put("RWA", "卢旺达 Rwanda");
        COUNTRY_MAP.put("BLM", "圣巴泰勒米 Saint Barthelemy");
        COUNTRY_MAP.put("SHN", "圣赫勒拿 Saint Helena");
        COUNTRY_MAP.put("KNA", "圣基茨和尼维斯 Saint Kitts and Nevis");
        COUNTRY_MAP.put("LCA", "圣卢西亚 Saint Lucia");
        COUNTRY_MAP.put("MAF", "圣马丁 Saint Martin");
        COUNTRY_MAP.put("SPM", "圣皮埃尔和密克隆 Saint Pierre and Miquelon");
        COUNTRY_MAP.put("VCT", "圣文森特和格林纳丁斯 Saint Vincent and the Grenadines");
        COUNTRY_MAP.put("WSM", "萨摩亚 Samoa");
        COUNTRY_MAP.put("SMR", "圣马力诺 San Marino");
        COUNTRY_MAP.put("STP", "圣多美和普林西比 Sao Tome and Principe");
        COUNTRY_MAP.put("SAU", "沙特阿拉伯 Saudi Arabia");
        COUNTRY_MAP.put("SEN", "塞内加尔 Senegal");
        COUNTRY_MAP.put("SRB", "塞尔维亚 Serbia");
        COUNTRY_MAP.put("SYC", "塞舌尔 Seychelles");
        COUNTRY_MAP.put("SLE", "塞拉利昂 Sierra Leone");
        COUNTRY_MAP.put("SGP", "新加坡 Singapore");
        COUNTRY_MAP.put("SXM", "圣马丁岛 Sint Maarten");
        COUNTRY_MAP.put("SVK", "斯洛伐克 Slovakia");
        COUNTRY_MAP.put("SVN", "斯洛文尼亚 Slovenia");
        COUNTRY_MAP.put("SLB", "所罗门群岛 Solomon Islands");
        COUNTRY_MAP.put("SOM", "索马里 Somalia");
        COUNTRY_MAP.put("ZAF", "南非 South Africa");
        COUNTRY_MAP.put("SGS", "南乔治亚和南桑威奇群岛 South Georgia and the South Sandwich Islands");
        COUNTRY_MAP.put("SSD", "南苏丹 South Sudan");
        COUNTRY_MAP.put("ESP", "西班牙 Spain");
        COUNTRY_MAP.put("LKA", "斯里兰卡 Sri Lanka");
        COUNTRY_MAP.put("SDN", "苏丹 Sudan");
        COUNTRY_MAP.put("SUR", "苏里南 Suriname");
        COUNTRY_MAP.put("SJM", "斯瓦尔巴和扬马延 Svalbard and Jan Mayen");
        COUNTRY_MAP.put("SWZ", "斯威士兰 Eswatini");
        COUNTRY_MAP.put("SWE", "瑞典 Sweden");
        COUNTRY_MAP.put("CHE", "瑞士 Switzerland");
        COUNTRY_MAP.put("SYR", "叙利亚 Syria");
        COUNTRY_MAP.put("TJK", "塔吉克斯坦 Tajikistan");
        COUNTRY_MAP.put("THA", "泰国 Thailand");
        COUNTRY_MAP.put("TLS", "东帝汶 Timor-Leste");
        COUNTRY_MAP.put("TGO", "多哥 Togo");
        COUNTRY_MAP.put("TKL", "托克劳 Tokelau");
        COUNTRY_MAP.put("TON", "汤加 Tonga");
        COUNTRY_MAP.put("TTO", "特立尼达和多巴哥 Trinidad and Tobago");
        COUNTRY_MAP.put("TUN", "突尼斯 Tunisia");
        COUNTRY_MAP.put("TUR", "土耳其 Turkey");
        COUNTRY_MAP.put("TKM", "土库曼斯坦 Turkmenistan");
        COUNTRY_MAP.put("TCA", "土耳其和凯科斯群岛 Turks and Caicos Islands");
        COUNTRY_MAP.put("TUV", "图瓦卢 Tuvalu");
        COUNTRY_MAP.put("UGA", "乌干达 Uganda");
        COUNTRY_MAP.put("UKR", "乌克兰 Ukraine");
        COUNTRY_MAP.put("ARE", "阿联酋 United Arab Emirates");
        COUNTRY_MAP.put("GBR", "英国 United Kingdom");
        COUNTRY_MAP.put("USA", "美国 United States");
        COUNTRY_MAP.put("URY", "乌拉圭 Uruguay");
        COUNTRY_MAP.put("UZB", "乌兹别克斯坦 Uzbekistan");
        COUNTRY_MAP.put("VUT", "瓦努阿图 Vanuatu");
        COUNTRY_MAP.put("VAT", "梵蒂冈 Vatican");
        COUNTRY_MAP.put("VEN", "委内瑞拉 Venezuela");
        COUNTRY_MAP.put("VNM", "越南 Vietnam");
        COUNTRY_MAP.put("VGB", "英属维尔京群岛 Virgin Islands, British");
        COUNTRY_MAP.put("VIR", "美属维尔京群岛 Virgin Islands, U.S.");
        COUNTRY_MAP.put("WLF", "瓦利斯和富图纳 Wallis and Futuna");
        COUNTRY_MAP.put("ESH", "西撒哈拉 Western Sahara");
        COUNTRY_MAP.put("YEM", "也门 Yemen");
        COUNTRY_MAP.put("ZMB", "赞比亚 Zambia");
        COUNTRY_MAP.put("ZWE", "津巴布韦 Zimbabwe");
    }

    public static void downloadAndZipAllLevel0GeoJson(String outputDir, String zipFilePath) throws IOException {
        File dir = new File(outputDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        // 开始下载
        List<String> filesToZip = new ArrayList<>();

        for (Map.Entry<String, String> entry : COUNTRY_MAP.entrySet()) {
            String iso3 = entry.getKey();
            String countryName = entry.getValue();
            String url = "https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_" + iso3 + "_0.json";
            String filename = "gadm41_" + iso3 + "_" + countryName + ".json";
            String path = outputDir + File.separator + filename;

            System.out.println("Downloading: " + countryName + " (" + iso3 + ") from " + url);

            try {
                downloadFile(url, path);
                filesToZip.add(path);
            } catch (IOException e) {
                System.err.println("❌ 下载失败: " + countryName + " (" + iso3 + ")");
            }
        }

        // 打包成 ZIP
        System.out.println("开始打包成 ZIP...");
        zipFiles(filesToZip, zipFilePath);

        // 删除临时文件夹
        for (String file : filesToZip) {
            new File(file).delete();
        }

        System.out.println("✅ 所有文件已打包完成: " + zipFilePath);
    }

    private static void downloadFile(String fileURL, String savePath) throws IOException {
        URL url = new URL(fileURL);
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        int responseCode = httpConn.getResponseCode();

        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP error code: " + responseCode);
        }

        try (InputStream inputStream = httpConn.getInputStream();
             FileOutputStream outputStream = new FileOutputStream(savePath)) {
            int bytesRead;
            byte[] buffer = new byte[4096];
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }
    }

    private static void zipFiles(List<String> filePaths, String zipFilePath) throws IOException {
        try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
            for (String filePath : filePaths) {
                File file = new File(filePath);
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOut.putNextEntry(zipEntry);

                try (FileInputStream fis = new FileInputStream(file)) {
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = fis.read(buffer)) > 0) {
                        zipOut.write(buffer, 0, len);
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        String outputDir = "gadm41_level0_temp";
        String zipFilePath = "gadm41_level0_all_countries.zip";

        try {
            downloadAndZipAllLevel0GeoJson(outputDir, zipFilePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
